/**
 * 防抖+节流的组合实现
 *
 * @param {function} cb 要执行的回调函数
 * @param {number} wait 要设置的防抖节流时间
 * @returns {function}
 * 
 * 思路：
 *   1. 第一次触发或者一直触发，考虑 throttle，定时响应一次（强制响应）
 *   2. 如果没有一直触发，则使用 debounce，响应最后一次请求
 */
const combinedDebounceThrottle = function(cb, wait) {
    // TODO：参数检查
    //   cb：function
    //   wait：number
    // 略(参照 debounce.js 或 throttle.js 部分)

    let lasttime = 0
    let timerDebounce = null
    let timerThrottle = null

    // 执行一次回调响应的处理部分
    function executeCb(...args) {
        clearTimeout(timerDebounce)
        clearTimeout(timerThrottle)
        timerDebounce = null
        timerThrottle = null
        lasttime = Date.now()
        cb.apply(null, args)
    }

    return function(...args) {
        const now = Date.now()
        const timespan = now - lasttime
        const isCoolingDown = timespan < wait

        clearTimeout(timerDebounce)

        // 如果一直 debounce 而没有执行响应，
        // 且，超过冷却时间，则强制执行一次
        if (!timerThrottle && !isCoolingDown) {
            timerThrottle = setTimeout(executeCb, wait, ...args)
        }
        // 如果不是一直触发，则在延迟时间后做一次响应（使用debounce）
        else {
            timerDebounce = setTimeout(executeCb, wait, ...args)
        }
    }
}